package com.p6spy.engine.event;

import com.p6spy.engine.common.PreparedStatementInformation;
import com.p6spy.engine.common.StatementInformation;

import java.sql.SQLException;

/**
 * This event listener offers more coarse grained event listener methods as it aggregates events for the execute* and
 * addBatch methods.
 */
public abstract class SimpleJdbcEventListener extends JdbcEventListener {

    /**
     * This callback method is executed before any {@link java.sql.Statement}.execute* method is invoked
     *
     * @param statementInformation The meta information about the {@link java.sql.Statement} being invoked
     */
    public void onBeforeAnyExecute(StatementInformation statementInformation) {
    }

    /**
     * This callback method is executed after any {@link java.sql.Statement}.execute* method is invoked
     *
     * @param statementInformation The meta information about the {@link java.sql.Statement} being invoked
     * @param timeElapsedNanos     The execution time of the execute call
     * @param e                    The {@link SQLException} which may be triggered by the call (<code>null</code> if
     *                             there was no exception).
     */
    public void onAfterAnyExecute(StatementInformation statementInformation, long timeElapsedNanos, SQLException e) {
    }

    /**
     * This callback method is executed before any {@link java.sql.Statement}.addBatch* method is invoked
     *
     * @param statementInformation The meta information about the {@link java.sql.Statement} being invoked
     */
    public void onBeforeAnyAddBatch(StatementInformation statementInformation) {
    }

    /**
     * This callback method is executed before any {@link java.sql.Statement}.addBatch* method is invoked
     *
     * @param statementInformation The meta information about the {@link java.sql.Statement} being invoked
     * @param timeElapsedNanos     The execution time of the execute call
     * @param e                    The {@link SQLException} which may be triggered by the call (<code>null</code> if
     *                             there was no exception).
     */
    public void onAfterAnyAddBatch(StatementInformation statementInformation, long timeElapsedNanos, SQLException e) {
    }

    @Override
    public void onBeforeExecute(PreparedStatementInformation statementInformation) {
        onBeforeAnyExecute(statementInformation);
    }

    @Override
    public void onBeforeExecute(StatementInformation statementInformation, String sql) {
        onBeforeAnyExecute(statementInformation);
    }

    @Override
    public void onBeforeExecuteBatch(StatementInformation statementInformation) {
        onBeforeAnyExecute(statementInformation);
    }

    @Override
    public void onBeforeExecuteUpdate(PreparedStatementInformation statementInformation) {
        onBeforeAnyExecute(statementInformation);
    }

    @Override
    public void onBeforeExecuteUpdate(StatementInformation statementInformation, String sql) {
        onBeforeAnyExecute(statementInformation);
    }

    @Override
    public void onBeforeExecuteQuery(PreparedStatementInformation statementInformation) {
        onBeforeAnyExecute(statementInformation);
    }

    @Override
    public void onBeforeExecuteQuery(StatementInformation statementInformation, String sql) {
        onBeforeAnyExecute(statementInformation);
    }

    @Override
    public void onAfterExecute(PreparedStatementInformation statementInformation, long timeElapsedNanos, SQLException e) {
        onAfterAnyExecute(statementInformation, timeElapsedNanos, e);
    }

    @Override
    public void onAfterExecute(StatementInformation statementInformation, long timeElapsedNanos, String sql, SQLException e) {
        onAfterAnyExecute(statementInformation, timeElapsedNanos, e);
    }

    @Override
    public void onAfterExecuteBatch(StatementInformation statementInformation, long timeElapsedNanos, int[] updateCounts, SQLException e) {
        onAfterAnyExecute(statementInformation, timeElapsedNanos, e);
    }

    @Override
    public void onAfterExecuteUpdate(PreparedStatementInformation statementInformation, long timeElapsedNanos, int rowCount, SQLException e) {
        onAfterAnyExecute(statementInformation, timeElapsedNanos, e);
    }

    @Override
    public void onAfterExecuteUpdate(StatementInformation statementInformation, long timeElapsedNanos, String sql, int rowCount, SQLException e) {
        onAfterAnyExecute(statementInformation, timeElapsedNanos, e);
    }

    @Override
    public void onAfterExecuteQuery(PreparedStatementInformation statementInformation, long timeElapsedNanos, SQLException e) {
        onAfterAnyExecute(statementInformation, timeElapsedNanos, e);
    }

    /**
     * 在查询执行完毕后调用的方法，用于监控和记录JDBC查询操作的相关信息。
     *
     * @param statementInformation 包含关于执行SQL语句的Statement对象相关信息的对象
     * @param timeElapsedNanos     从开始执行查询到查询结束所花费的时间（单位：纳秒）
     * @param sql                  执行的具体SQL查询语句
     * @param e                    如果在执行查询过程中发生了SQLException异常，则传递该异常；若无异常，则为null
     */
    @Override
    public void onAfterExecuteQuery(StatementInformation statementInformation, long timeElapsedNanos, String sql, SQLException e) {
        // 调用通用的查询执行完成后的处理方法
        onAfterAnyExecute(statementInformation, timeElapsedNanos, e);
    }


    @Override
    public void onBeforeAddBatch(PreparedStatementInformation statementInformation) {
        onBeforeAnyAddBatch(statementInformation);
    }

    @Override
    public void onBeforeAddBatch(StatementInformation statementInformation, String sql) {
        onBeforeAnyAddBatch(statementInformation);
    }

    @Override
    public void onAfterAddBatch(PreparedStatementInformation statementInformation, long timeElapsedNanos, SQLException e) {
        onAfterAnyAddBatch(statementInformation, timeElapsedNanos, e);
    }

    @Override
    public void onAfterAddBatch(StatementInformation statementInformation, long timeElapsedNanos, String sql, SQLException e) {
        onAfterAnyAddBatch(statementInformation, timeElapsedNanos, e);
    }
}
